package main

import (
	"encoding/json"
	"flag"
	"github.com/prometheus/client_golang/prometheus"
	"log"
	"net"
	"net/http"
	"os"

	"github.com/prometheus/client_golang/prometheus/promhttp"
)

var version = "v1.1"
var listenAddressPort = flag.String("addressPort", "0.0.0.0:8080", "server listen address and port: format: 192.168.1.1:8080")

type ReturnInfo struct {
	Version    string
	ClientIP   string
	ServerName string
	ServerIP   string
}

// WebRequestTotal 初始化web_request_total, counter类型指标，表示接收到的http请求的总次数
var WebRequestTotal = prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Name: "web_request_total",
		Help: "Number of request in total",
	},

	// 设置两个标签，请求方法和路径 对请求总次数在两个
	[]string{"method", "endpoint"},
)

// WebRequestDurationSeconds web_request_duration_seconds, Histogram类型指标，Bucket代表Duration的分布区间
var WebRequestDurationSeconds = prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "web_request_duration_seconds",
		Help:    "web request duration seconds distribution",
		Buckets: []float64{0.1, 0.3, 0.5, 0.7, 0.9, 1, 2, 3, 5, 10},
	},
	// 设置两个标签，请求方法和路径 对请求总次数在两个
	[]string{"method", "endpoint"},
)

func init() {
	// 注册监控指标
	prometheus.MustRegister(WebRequestTotal)
	prometheus.MustRegister(WebRequestDurationSeconds)
}

func main() {
	flag.Parse()
	// create a new mux server
	server := http.NewServeMux()
	// register a new handler for the / endpoint
	server.HandleFunc("/", Monitor(home))
	// register a new handler for the /metrics endpoint
	server.Handle("/metrics", promhttp.Handler())
	log.Fatal(http.ListenAndServe(*listenAddressPort, server))
}

func home(resp http.ResponseWriter, req *http.Request) {

	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	addr, err := net.ResolveIPAddr("ip", hostname)
	if err != nil {
		panic(err)
	}

	clientIP := req.RemoteAddr

	returnInfo := ReturnInfo{
		Version:    version,
		ClientIP:   clientIP,
		ServerName: hostname,
		ServerIP:   addr.IP.String(),
	}
	ri, err := json.Marshal(returnInfo)
	if err != nil {
		panic(err)
	}

	log.Printf("CLIENT: %s, PATH: %s, METHOD: %s", clientIP, req.RequestURI, req.Method)
	resp.Write(ri)
}
